/**********************************************************************
 *	(fill this)
**********************************************************************/
// `include "freqDiv.v"
// `include "../keyDebounce/keyHold.v"
// `include "../keyDebounce/keyFilter.v"
// `include "../TimeBlock/timeTop.v"
// `include "../AlarmBlock/alarmTop.v"
// `include "../DisplayBlock/displayTop.v"
// `include "../Buzzer/buzzer.v"
// `include "../Buzzer/buzzerCtrl.v"

//`define DEBUG

module clockTop #(
	parameter	SYS_CLK = 50_000_000
)(
  input  wire         rstn    ,
  input  wire         sys_clk ,
  
  input  wire         set_time,       // SetTime mode on/off(1 or 0).
  input  wire         set_hour,       // Hour plus 1 everytime press this key.
  input  wire         set_min ,       // Minute plus 1 everytime press this key.
  input  wire         set_alarm,      // Display and set alarm on/off(1 or 0).
  input  wire         toggle  ,       // Alarm on/off(1 or 0).

  output wire [15:0]  hour    ,
	output wire [15:0]	min  		,
	output wire [15:0]	sec			,

`ifdef DEBUG
  output wire [7:0]  t_hour,
  output wire [7:0]  t_min ,
  output wire [7:0]  t_sec ,
  output wire [7:0]  a_hour,
  output wire [7:0]  a_min ,
  output wire [7:0]  a_sec ,
`endif

  // output wire [5:0]   sel     ,       // select the digital tube
  output wire         beep    
);


`ifndef DEBUG
wire        clk_1;

wire [7:0]  t_hour;
wire [7:0]  t_min ;
wire [7:0]  t_sec ;
wire [7:0]  a_hour;
wire [7:0]  a_min ;
wire [7:0]  a_sec ;

/* verilator lint_off UNOPTFLAT */
wire        set_time_kf;
wire        set_hour_kf;
wire        set_min_kf ;
wire        set_alarm_kf;
`endif

// wire [15:0] disp_hour  ;
// wire [15:0] disp_min   ;
// wire [15:0] disp_sec   ; 

wire        beep_en;

`ifndef DEBUG
freqDiv #(
  .SYS_CLK    (   SYS_CLK  	)
) freqDiv_inst (
  .sys_clk    (   sys_clk     ),
  .rstn       (   rstn        ),

  .clk_1      (   clk_1       )
  // .clk        (   clk         )
);

keyHold #(
  .SYS_CLK    (   SYS_CLK   )
) setTime(
  .clk        (     sys_clk     ),
  .rstn       (     rstn        ),
  .ikey       (     set_time    ),

  .okey       (     set_time_kf )
);

keyHold #(
  .SYS_CLK    (   SYS_CLK   )
) setAlarm(
  .clk        (     sys_clk     ),
  .rstn       (     rstn        ),
  .ikey       (     set_alarm   ),

  .okey       (     set_alarm_kf)
);

keyFilter #(
  .SYS_CLK    (   SYS_CLK   )
) setHour(
  .clk        (     sys_clk     ),
  .rstn       (     rstn        ),
  .ikey       (     set_hour    ),

  .okey       (     set_hour_kf )
);

keyFilter #(
  .SYS_CLK    (   SYS_CLK   )
) setMin(
  .clk        (     sys_clk     ),
  .rstn       (     rstn        ),
  .ikey       (     set_min     ),

  .okey       (     set_min_kf  )
);
`endif

timeTop timeBlock (
  .rstn       (     rstn        ),

`ifdef DEBUG
  .clk        (     sys_clk     ),
  .set_time   (     set_time    ),
  .set_hour   (     set_hour    ),
  .set_min    (     set_min     ),
`else
  .clk        (     clk_1       ),
  .set_time   (     set_time_kf ),
  .set_hour   (     set_hour_kf ),
  .set_min    (     set_min_kf  ),
`endif

  .hour       (     t_hour      ),
  .min        (     t_min       ),
  .sec        (     t_sec       )
);

alarmTop alarmBlock (
  .rstn       (     rstn        ),

`ifdef DEBUG
  .clk        (     sys_clk     ),
  .set_alarm  (     set_alarm   ),
  .set_hour   (     set_hour    ),
  .set_min    (     set_min     ),
`else
  .clk        (     clk_1       ),
  .set_alarm  (     set_alarm_kf),
  .set_hour   (     set_hour_kf ),
  .set_min    (     set_min_kf  ),
`endif

  .hour       (     a_hour      ),
  .min        (     a_min       ),
  .sec        (     a_sec       )
);

displayTop displayBlock(
`ifdef DEBUG
  .alarm       (      set_alarm   ),
`else
  .alarm       (      set_alarm_kf),
`endif
  .t_hour      (      t_hour      ),
  .t_min       (      t_min       ),
  .t_sec       (      t_sec       ),

  .a_hour      (      a_hour      ),
  .a_min       (      a_min       ),
  .a_sec       (      a_sec       ),

  .dig_hour_u  (   		hour[15:8] ),
  .dig_hour_l  (   		hour[7:0]  ),
  .dig_min_u   (   		min[15:8]  ),
  .dig_min_l   (   		min[7:0]   ),
  .dig_sec_u	 (   		sec[15:8]  ),
  .dig_sec_l   (   		sec[7:0]   )
);

/******************************************************************
 *  Depends on your own FPGA board.
 ******************************************************************
dynamicScan #(
  .SYS_CLK    (   SYS_CLK   )
) dynamicScan_inst (
  .clk        (       sys_clk     ),
  .rstn       (       rstn        ),

  .hourUpper  (    disp_hour[15:8] ),
  .hourLow    (    disp_hour[7:0]  ),
  .minUpper   (    disp_min[15:8]  ),
  .minLow     (    disp_min[7:0]   ),
  .secUpper   (    disp_sec[15:8]  ),
  .secLow     (    disp_sec[7:0]   ),

  .digDisp    (       disp        ),
  .sel        (       sel         )
);    

*************************************************************/

/*******************************************************
 *  Optional for alarm buzzer.
 *******************************************************/
buzzerCtrl #(
  .SYS_CLK    (   SYS_CLK   )
) buzzerCtrl_inst (
  .clk        (       sys_clk     ),
  .rstn       (       rstn        ),
  .ena        (       toggle      ),

  .t_hour     (       t_hour      ),
  .t_min      (       t_min       ),
  .t_sec      (       t_sec       ),

  .a_hour     (       a_hour      ),
  .a_min      (       a_min       ),
  .a_sec      (       a_sec       ),

  .beep_en    (       beep_en     )
);

buzzer #(
  .SYS_CLK    (   SYS_CLK   ),
  .PITCH      (     1318    ) 
) buzzer_inst (
  .clk        (       sys_clk     ),
  .rstn       (       rstn        ),
  .ena        (       beep_en     ),

  .beep       (       beep        )
);

endmodule
